package com.yc.sole.framework.exception;

import com.yc.sole.framework.enums.ValidatedEnum;
import com.yc.sole.framework.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

import java.util.Objects;

/**
 * @author yizuomin
 * @date 2022/11/19 13:11
 **/
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 系统异常
     */
    @ExceptionHandler(Exception.class)
    public Result<Void> handleException(Exception e) {
        e.printStackTrace();
        return Result.error("服务异常:" + e.getMessage());
    }

    /**
     * 文件上传大小超出限制异常
     */
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public Result<Void> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) {
        log.error("exception:{}", e.getMessage());
        return Result.error("文件上传大小超出限制");
    }

    /**
     * 业务异常
     */
    @ExceptionHandler(BaseException.class)
    public Result<Void> handleException(BaseException e) {
        e.printStackTrace();
        return Result.fail(e.getCode(), e.getMessage());
    }

    /**
     * 参数验证异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(BindException.class)
    public Result<Void> handelBindException(BindException e) {
        if (e.hasFieldErrors()) {
            return Result.fail(Objects.requireNonNull(e.getFieldError()).getDefaultMessage());
        }
        return Result.fail(e.getMessage());
    }

    /**
     * 数据重复
     *
     * @param e
     * @return
     */
    @ExceptionHandler(DuplicateKeyException.class)
    public Result<Void> handleDuplicateKeyException(DuplicateKeyException e) {
        log.error("exception:{}", e.getMessage());
        return Result.fail("已存在重复数据，请检查！");
    }

    /**
     * 自定义验证异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<Void> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("发生MethodArgumentNotValidException...", e);
        BindingResult bindingResult = e.getBindingResult();
        String errorMessage = "";
        if (bindingResult.hasErrors()) {
            FieldError fieldError = bindingResult.getFieldError();
            if (fieldError != null) {
                ValidatedEnum validatedEnum = ValidatedEnum.getInstanceByFieldError(fieldError);
                if (Objects.nonNull(validatedEnum)) {
                    //存在ValidatedEnum枚举对象中，使用对应提示
                    errorMessage = validatedEnum.getMessage();
                } else {
                    //不存在则使用默认提示或者使用手动编写message提示
                    errorMessage = fieldError.getDefaultMessage();
                }
            }
        }
        return Result.fail(errorMessage);
    }
}
